package utils;

import java.io.IOException;

import logger.Log;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;


public class Utils {
	
	static Log log;
	

	public static void waitForElementPresent(final WebDriver driver, final By by) throws Exception {
		try {
			new WebDriverWait(driver, Config.getInstance().getTimeWaitForElementPresentSeconds()).until(new ExpectedCondition<Boolean>() {
	            public Boolean apply(WebDriver webDriver) {
	                return isElementPresent(driver,by);
	            }
	        });
		} catch (NoSuchElementException e) {
			throw new Exception("Nie znaleziono elementu: " + by.toString());
		}
	}
	
	public static void waitForElementNotPresent(final WebDriver driver, final By by) throws Exception {
		try {
			
			new WebDriverWait(driver, Config.getInstance().getTimeWaitForElementPresentSeconds(), 1)
			.until(new ExpectedCondition<Boolean>() {
				int licznik=0;
				public Boolean apply(WebDriver d) {
					Boolean czy_obecny = isElementPresent(driver,by);
					//System.out.println("Licznik: "+licznik);
					licznik++;
					if(!czy_obecny) return true;
					else return false;
				}
			});
			
			
		} catch (NoSuchElementException e) {
			throw new Exception("Nie znaleziono elementu: " + by.toString());
		}
	}
	
	public static boolean isElementPresent(WebDriver driver, By by) {
		try {
			driver.findElement(by);
			return true;
		} catch (NoSuchElementException e) {
			return false;
		}
	}
	
	public static JavascriptExecutor javascriptExecutor(WebDriver driver) {
		return (JavascriptExecutor) driver;
	}
	
	public static boolean safeJSExecutor(WebDriver driver, String polecenieJS) throws Exception
	{
		launchLog();
		int licz = 0;
		
		while (licz < Config.getInstance().getMaxTryCountAction() && !executeJS(driver, polecenieJS)) {
			Thread.sleep(Config.getInstance().getThreadSleepBeforeTryActionMilis());
			licz++;
			log.info("safeJSExecutor()  ILOSC PROB: "+licz+"  Obiekt: "+Utils.class +"  Polecenie:  "+polecenieJS);
		}
		
		if(licz>=Config.getInstance().getMaxTryCountAction())
		{
			log.info("safeJSExecutor() PRZEKROCZONO ILOSC PROB: "+licz+"  Polecenie: "+polecenieJS);
			throw new Exception("safeJSExecutor() PRZEKROCZONO ILOSC PROB: "+licz+"  Polecenie: "+polecenieJS);
		}
		
		
		return true;
	}
	
	private static boolean executeJS(WebDriver driver, String polecenieJS)
	{
		try {

			javascriptExecutor(driver).executeScript(polecenieJS);
			return true;
		}catch (Exception e) {
			return false;
		}
		
	}
	
	private static void launchLog()
	{
		try {
			log = new Log(Utils.class);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static String byToString(By by)
	{
		String nazwa = by.toString();
		String [] byTags = {"By.id: ", "By.linkText: ", "By.partialLinkText: ", "By.name: ",
				"By.tagName: ", "By.xpath: ", "By.className: ", "By.selector: "};
		for (String zm : byTags) {
			if(nazwa.contains(zm)){
				nazwa=nazwa.replace(zm, "");
			}
		}
		return nazwa;
	}
	
	/*public static boolean safeClickLinkText(WebDriver driver, By fieldName) {
		
		try {
			driver.findElement(fieldName).click();
			return true;
		} catch (StaleElementReferenceException e) {
			return false;
		}
	}
	
	public static boolean safeClickWhileLoopNeeded(WebDriver driver, By fieldName) {
		
		try {
			
			Actions a = new Actions(driver);
			a.click(driver.findElement(fieldName));
			a.perform();
			return true;
		} catch (TimeoutException e) {
			return false;
		}
	}
	

	
	public static boolean safeFindFieldObject(WebDriver driver, By fieldName) {
		try {
			driver.findElement(fieldName);
			return true;
		} catch (TimeoutException e) {
			return false;
		} catch(NoSuchElementException ns) {
			return false;
		}
	}
	
	public static boolean doubleClick(WebDriver driver, WebElement fieldObject) {
		
		Actions a = new Actions(driver);
		a.doubleClick(fieldObject);
		a.perform();
		
		return false;

	}*/
	


}
